import numpy as np
import generate_chrom_po_p95
import po_p95_explainer
import po_p95_GA_operators
import numpy_basic_operators

# 生成一个初始的合法染色体种群
variable_num = 18
pop_size = 20
next_generate_method = 1
chrom_format = [variable_num - 1, variable_num, pop_size]
legal_chrom = np.empty((0, variable_num))

while legal_chrom.shape[0] < pop_size * 2:
    original_chrom = generate_chrom_po_p95.generate_chrom(pop_size, variable_num)
    temp_legal_chrom = po_p95_explainer.restriction_function(original_chrom, variable_num)
    legal_chrom = np.vstack((legal_chrom, temp_legal_chrom))
    legal_chrom = np.unique(legal_chrom, axis=0)

weight = np.array([0.3, 0.3, 0.4])
legal_chrom = np.int16(legal_chrom)
legal_chrom_with_objective = po_p95_explainer.get_objective_value(legal_chrom, 'geneCode.txt', weight)
current_chrom, chrom_left = po_p95_GA_operators.chose_operator(legal_chrom_with_objective, chrom_format, 1, pop_size)
best_performance_list = []  # 用于存储每次迭代的最优值

if next_generate_method == 1:
    for iter_times in range(101):
        chrom_better, chrom_worse = po_p95_GA_operators.chose_operator(current_chrom, chrom_format, 1, pop_size // 2)
        chrom_to_keep, _ = po_p95_GA_operators.chose_operator(current_chrom, chrom_format, 1, pop_size // 2)
        check_unique = chrom_to_keep[:, 0:variable_num]
        mutate_possibility = 0.5
        child_from_cross_hybrid_and_mutate = np.empty((0, variable_num))

        # 较优-较差种群混合交叉和变异
        while child_from_cross_hybrid_and_mutate.shape[0] < pop_size // 2:
            crossed_chrom = po_p95_GA_operators.cross_operator(chrom_better, chrom_worse, chrom_format)
            mutate_indv_indices = np.random.choice(chrom_worse.shape[0], np.int16(chrom_worse.shape[0] * mutate_possibility), False)
            indv_to_mutate = chrom_worse[mutate_indv_indices, :]
            mutated_chrom = po_p95_GA_operators.mutate_operator(indv_to_mutate, chrom_format, mutate_pos_num=1)
            temp_child_chrom = np.vstack((crossed_chrom, mutated_chrom))
            filtered_temp_child_chrom = np.unique(temp_child_chrom, axis=0)
            filtered_temp_child_chrom = numpy_basic_operators.delete_identical_lines(check_unique, filtered_temp_child_chrom, 1)

            # 确保 filtered_temp_child_chrom 的形状正确
            if filtered_temp_child_chrom.shape[0] == 0:
                continue

            # 确保 filtered_temp_child_chrom 的内容是整数
            filtered_temp_child_chrom = np.int16(filtered_temp_child_chrom)

            # 确保 filtered_temp_child_chrom 没有重复的行
            filtered_temp_child_chrom = np.unique(filtered_temp_child_chrom, axis=0)

            temp_legal_child_chrom = po_p95_explainer.restriction_function(filtered_temp_child_chrom, variable_num)
            child_from_cross_hybrid_and_mutate = np.vstack((child_from_cross_hybrid_and_mutate, temp_legal_child_chrom))

        temp_indices = np.random.choice(child_from_cross_hybrid_and_mutate.shape[0], pop_size // 2, False)
        child_from_cross_hybrid_and_mutate = child_from_cross_hybrid_and_mutate[temp_indices, :]

        child_chrom = np.vstack((child_from_cross_hybrid_and_mutate))
        child_chrom = np.int16(child_chrom)
        child_chrom_with_objective = po_p95_explainer.get_objective_value(child_chrom, 'geneCode.txt', weight)
        current_chrom = np.vstack((chrom_to_keep, child_chrom_with_objective))

        best_performance = np.min(current_chrom[:, chrom_format[1]])
        best_performance_list.append(best_performance)

        if iter_times % 10 == 0:
            print(current_chrom)
        else:
            pass
        print(iter_times)
        print(f"Best Performance: {best_performance}")
